import { isUndefined, isNull, toString, PageParams, PagedList } from "mmb";
import * as activity_user_awardpb from "../grpc-client/service/activity_user_award_pb";
import {
  getBgsActivityUserAwardOpSafely,
  getMetadata,
  getOptionsOfLight,
  wrapperGrpcError,
} from "../grpc-client/grpcAdapter";
import {
  RealPrizeSku,
  RealPrizeProduct,
  ActivityUserAwardForC,
  ActivityAwardAsReporter,
} from "./declareTypes";
import AwardType from "../bg-enums/awardType";
import ActivityType from "../bg-enums/activityType";
import DeliveryMode from "../bg-enums/deliveryMode";
import {
  productAttributeDefPbToObject,
  pbTimestampToJs,
  jsTimestampToPb,
} from "./helper";
/****************************************************************************************/
/*                                   activity_user_procedure entity                     */
/****************************************************************************************/

const realPrizeSkuEntityPbToObject = (
  pb: activity_user_awardpb.RealPrizeSkuEntity
): RealPrizeSku => {
  return {
    productId: toString(pb.getProductId()),
    productSpecId: toString(pb.getProductSpecId()),
    storageKey: pb.getStorageKey(),
    price: pb.getPrice(),
    skuName: pb.getSkuName(),
  };
};

const realPrizeProductEntityPbToObject = (
  pb: activity_user_awardpb.RealPrizeProductEntity
): RealPrizeProduct => {
  return {
    productId: toString(pb.getProductId()),
    productName: pb.getProductName(),
    productPics: pb.getProductPicsList(),
    priceMin: pb.getPriceMin(),
    priceMax: pb.getPriceMax(),
    quantity: pb.getQuantity(),
    productAttributeDefs: pb
      .getProductAttributeDefsList()
      .map(productAttributeDefPbToObject),
    skus: pb.getSkusList().map(realPrizeSkuEntityPbToObject),
  };
};

const activityUserAwardPbToObject = (
  pb: activity_user_awardpb.ActivityUserAwardForCEntity
): ActivityUserAwardForC => {
  return {
    awardId: toString(pb.getAwardId()),
    brandId: toString(pb.getBrandId()),
    activityId: toString(pb.getActivityId()),
    userId: toString(pb.getUserId()),
    awarded: pbTimestampToJs(pb.getAwarded())!,
    needRedeemByMannual: pb.getNeedRedeemByMannual(),
    redeemDeadlineAt: pbTimestampToJs(pb.getRedeemDeadlineAt())!,
    isRedeemed: pb.getIsRedeemed(),
    redeemed: pbTimestampToJs(pb.getRedeemed()),
    orderSerialNumber: pb.getOrderSerialNumber(),
    orderPaymentDeadlineAt: pbTimestampToJs(pb.getOrderPaymentDeadlineAt()),
    awardType: pb.getAwardType() as AwardType,
    brandName: pb.getBrandName(),
    brandTel: pb.getBrandTel(),
    activityName: pb.getActivityName(),
    activityType: pb.getActivityType() as ActivityType,
    activityTel: pb.getActivityTel(),
    winnerNickName: pb.getWinnerNickName(),
    winnerPic: pb.getWinnerPic(),
    winnerTel: pb.getWinnerTel(),
    bCoins: pb.getBCoins(),
    realPrizeProducts: pb
      .getRealPrizeProductsList()
      .map(realPrizeProductEntityPbToObject),
    warehouseId: toString(pb.getWarehouseId()),
    deliveryModes: pb.getDeliveryModesList().map((dm) => dm as DeliveryMode),
    shippingFee: pb.getShippingFee(),
  };
};

const activityAwardAsReporterPbToObject = (
  pb: activity_user_awardpb.ActivityAwardAsReporterEntity
): ActivityAwardAsReporter => {
  return {
    userNickName: pb.getUserNickName(),
    desc: pb.getDesc(),
    awarded: pbTimestampToJs(pb.getAwarded())!,
  };
};

/****************************************************************************************/
/*                                   activity_user_procedure cmd                        */
/****************************************************************************************/

/****************************************************************************************/
/*                                   activity_user_procedure query                      */
/****************************************************************************************/

export interface ListActivityUserAwardsByActivityIDAndUserIDAndAwardTypeParam {
  activityId: string;
  userId: string;
  awardType: AwardType;
}

export const listActivityUserAwardsByActivityIDAndUserIDAndAwardType = async (
  {
    activityId,
    userId,
    awardType,
  }: ListActivityUserAwardsByActivityIDAndUserIDAndAwardTypeParam,
  pager: PageParams
): Promise<PagedList<ActivityUserAwardForC>> => {
  const cl = getBgsActivityUserAwardOpSafely();
  const req = new activity_user_awardpb.ListActivityUserAwardsByActivityIDAndUserIDAndAwardTypeRequest();

  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setTs(jsTimestampToPb(pager.ts));
  req.setActivityId(Number(activityId));
  req.setUserId(Number(userId));
  req.setAwardType(awardType);

  return new Promise((resolve, reject) => {
    cl.listActivityUserAwardsByActivityIDAndUserIDAndAwardType(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<ActivityUserAwardForC> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res
          .getActivityUserAwardsList()
          .map(activityUserAwardPbToObject);
        resolve(ret);
      }
    );
  });
};

export const listActivityAwardsByActivityIDAsReporter = async (
  activityId: string,
  pager: PageParams
): Promise<PagedList<ActivityAwardAsReporter>> => {
  const cl = getBgsActivityUserAwardOpSafely();
  const req = new activity_user_awardpb.ListActivityAwardsByActivityIDAsReporterRequest();

  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setTs(jsTimestampToPb(pager.ts));
  req.setActivityId(Number(activityId));

  return new Promise((resolve, reject) => {
    cl.listActivityAwardsByActivityIDAsReporter(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<ActivityAwardAsReporter> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res
          .getActivityAwardsAsReporterList()
          .map(activityAwardAsReporterPbToObject);
        resolve(ret);
      }
    );
  });
};
